/**
* @program: src
*
* @description:
*
* @author: Mr.chen
*
* @create: 2020-11-20 15:49
**/
package models

import (

	"ydd-im/service/api/tools/util"
	mydb "ydd-im/service/dbproxy/util/mysql/conn"
	"database/sql"
	"errors"
	"fmt"
	"strings"
	"time"
)

type GroupContact struct {
	Id            int       `db:"id" json:"id"`
	Ownerid       int       `db:"ownerid" json:"ownerid"` // userid
	Dstid         int       `db:"dstid" json:"dstid"` //群id
	Cate          int       `db:"cate" json:"cate"` // 分类
	Memo          string    `db:"memo" json:"memo"` // 描述
	Createtime    time.Time `db:"createtime" json:"-"`
	Createtimestr string    `json:"createat"` // 创建时间
	GroupName     string    `db:"groupname" json:"groupname"` // 群名称
	Isowner       int       `db:"isowner" json:"isowner"` // 是否是群主
}

//orm 回调
func (gc *GroupContact) TableName() string {
	return TNGroupContact()
}

func NewGroupContact() *GroupContact {
	return &GroupContact{}
}
func (gc *GroupContact) AddGroupContact(groupcontact *GroupContact) (insertid int64, err error) {
	sqlStr := "insert  into " + gc.TableName() + "(ownerid,dstid,cate,memo,createtime,isowner) values (?,?,?,?,?,?)"
	dbconn,err := mydb.DBConn("")
	if err != nil {
		return 0, err
	}
	ret, err := dbconn.Exec(sqlStr, groupcontact.Ownerid, groupcontact.Dstid, groupcontact.Cate, groupcontact.Memo, groupcontact.Createtime,groupcontact.Isowner)
	if err != nil {
		return 0, err
	}
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil {
		return 0, err
	}
	return theID, nil
}

// 根据群ID,用户ID判断群是否存在
func (gc *GroupContact) GetGroupContactByCondition(userid, groupid int) (groupContact GroupContact, err error) {
	groupContact = GroupContact{}
	us := &User{}
	group := &Group{}
	sqlStr := "select a.id,a.ownerid,a.dstid,a.memo,c.memo as groupname   from " + gc.TableName() + " as a inner join " + us.TableName() + " as b on a.ownerid = b.id  inner join  " + group.TableName() + " as c  on a.dstid = c.id   where a.ownerid = ? and  a.dstid = ? and a.cate = 0 "

	dbconn,err := mydb.DBConn("r")
	if err != nil {
		return groupContact, err
	}
	err = dbconn.Get(&groupContact, sqlStr, userid, groupid)
	if err == sql.ErrNoRows { // 为空
		return groupContact, nil
	}
	if err != nil {
		return groupContact, err
	}
	return groupContact, nil
}

/**
 * 获取群记录
 * @access  public
 * @param   int     sid     签名所属Id
 * @param   int     userid   用户id
 * @return  []slice group   群列表
 * @return  error  err  错误信息
 */
func (gc *GroupContact) GetAllGroupContactJoinGroupList(sid, userid int) (group []Group, err error) {
	group = []Group{}
	u := &User{}
	g := &Group{}
	var where []string
	if sid > 0 {
		where = append(where, fmt.Sprintf("c.sid = %d", sid))
	}
	if userid > 0 {
		where = append(where, fmt.Sprintf("a.ownerid = %d", userid))
	}
	sqlStr := "select b.id, b.name,b.ownerid,b.icon,DATE_FORMAT(b.createtime, '%Y-%m-%d %T') as createtimestr,1 as isingroup from " + gc.TableName() + " as a inner join " + g.TableName() + " as b on a.dstid = b.id and b.cate=0 "
	sqlStr += " inner join " + u.TableName() + " as c on a.ownerid = c.id "
	if len(where) > 0 {
		whereStr := fmt.Sprintf(" WHERE %s", strings.Join(where, " AND "))
		isok := util.FilteredSQLInject(whereStr)
		if (isok) {
			return group, errors.New("参数有误，请重试！")
		}
		sqlStr += whereStr
	}
	sqlStr += " order by b.id asc"
	dbconn,err := mydb.DBConn("r")
	if err != nil {
		return group, err
	}
	err = dbconn.Select(&group, sqlStr)
	if err == sql.ErrNoRows { // 为空
		return group, nil
	}
	if err != nil {
		return group, err
	}
	return group, nil
}

/**
 * 获取群成员记录
 * @access  public
 * @param   []string     where     条件
 * @param   string     field   获取的列
 * @param   int     pageNumber   第几页，从1开始
 * @param   int     pageCount   每页的数量
 * @param   string     orderby   排序
 * @return  []slice group   群列表
 * @return  error  err  错误信息
 */
func (gc *GroupContact) GetAllGroupContactList(where []string, field string, pageNumber, pageCount int, orderby string) (groupContact []GroupContact, err error) {
	groupContact = []GroupContact{}
	if len(field) == 0 {
		field = "*"
	}
	sqlStr := "select " + field + " from " + gc.TableName()
	if len(where) > 0 {
		whereStr := fmt.Sprintf(" WHERE %s", strings.Join(where, " AND "))
		isok := util.FilteredSQLInject(whereStr)
		if (isok) {
			return groupContact, errors.New("参数有误，请重试！")
		}
		sqlStr += whereStr
	}
	if len(orderby) == 0 {
		sqlStr += " order by id asc"
	} else {
		sqlStr += " " + orderby
	}
	var firstlimit, endlimit int
	if pageCount > 0 {
		if pageNumber <= 1 {
			pageNumber = 1
		}
		firstlimit = (pageNumber - 1) * pageCount;;
		endlimit = pageCount;
		sqlStr += fmt.Sprintf(" limit %d,%d ", firstlimit, endlimit)
	} else {
		firstlimit = 0;
		endlimit = 0;
	}
	dbconn,err := mydb.DBConn("r")
	if err != nil {
		return groupContact, err
	}
	err = dbconn.Select(&groupContact, sqlStr)
	if err == sql.ErrNoRows { // 为空
		return groupContact, nil
	}
	if err != nil {
		return groupContact, err
	}
	return groupContact, nil
}

/**
 * 插入多条记录
 * @access  public
 * @param  []*GroupContact     groupContact     条件
 * @param   int     insertid   插入id
 * @param   error     err   错误
 * @return  error  err  错误信息
 */
// BatchInsertMessageArrive 自行构造批量插入的语句 https://www.liwenzhou.com/posts/Go/sqlx_bulk_insert/
func (gc *GroupContact) BatchInsertGroupContact(groupContact []*GroupContact) (insertid int64, err error) {
	// 存放 (?, ?) 的slice
	valueStrings := make([]string, 0, len(groupContact))
	// 存放values的slice
	valueArgs := make([]interface{}, 0, len(groupContact)*2)
	// 遍历users准备相关数据
	for _, m := range groupContact {
		// 此处占位符要与插入值的个数对应
		valueStrings = append(valueStrings, "(?,?,?,?,?,?)")
		valueArgs = append(valueArgs, m.Ownerid)
		valueArgs = append(valueArgs, m.Dstid)
		valueArgs = append(valueArgs, m.Cate)
		valueArgs = append(valueArgs, m.Memo)
		valueArgs = append(valueArgs, m.Createtime)
		valueArgs = append(valueArgs, m.Isowner)
	}
	valueStr := strings.Join(valueStrings, ",")
	isok := util.FilteredSQLInject(valueStr)
	if (isok) {
		return 0, errors.New("参数有误，请重试！")
	}
	// 自行拼接要执行的具体语句
	sqlStr := fmt.Sprintf("INSERT INTO "+gc.TableName()+"(ownerid,dstid,cate,memo,createtime,isowner) VALUES %s",
		valueStr)
	dbconn,err := mydb.DBConn("w")
	dbconn.Begin()
	if err != nil {
		return 0, err
	}
	ret, err := dbconn.Exec(sqlStr, valueArgs...)
	if err != nil {
		return 0, err
	}
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil {
		return 0, err
	}
	return theID, nil

}
/**
 * 获取数组中的某一列
 * @param array arr 数组
 * @param string key_name  列名
 * @return array  返回那一列的数组
 */
func (gc *GroupContact)  Get_arr_column(arr []GroupContact) (newArr []int,set map[string]bool) {
	newArr = make([]int, 0)
	set = make(map[string]bool,0)
	for k, _ := range arr {
		newArr = append(newArr, arr[k].Ownerid)
		set[fmt.Sprintf("%d",arr[k].Ownerid)] = true
	}
	return newArr,set
}

/**
 * 插入多条记录
 * @access  public
 * @param  []*GroupContact     groupContact     条件
 * @param   int     insertid   插入id
 * @param   error     err   错误
 * @return  error  err  错误信息
 */
// BatchInsertMessageArrive 自行构造批量插入的语句 https://www.liwenzhou.com/posts/Go/sqlx_bulk_insert/
func (gc *GroupContact) BatchInsertGroupContactTx(dbconn *sql.Tx,groupContact []*GroupContact) (insertid int64, err error) {
	// 存放 (?, ?) 的slice
	valueStrings := make([]string, 0, len(groupContact))
	// 存放values的slice
	valueArgs := make([]interface{}, 0, len(groupContact)*2)
	// 遍历users准备相关数据
	for _, m := range groupContact {
		// 此处占位符要与插入值的个数对应
		valueStrings = append(valueStrings, "(?,?,?,?,?,?)")
		valueArgs = append(valueArgs, m.Ownerid)
		valueArgs = append(valueArgs, m.Dstid)
		valueArgs = append(valueArgs, m.Cate)
		valueArgs = append(valueArgs, m.Memo)
		valueArgs = append(valueArgs, m.Createtime)
		valueArgs = append(valueArgs, m.Isowner)
	}
	valueStr := strings.Join(valueStrings, ",")
	isok := util.FilteredSQLInject(valueStr)
	if (isok) {
		return 0, errors.New("参数有误，请重试！")
	}
	// 自行拼接要执行的具体语句
	sqlStr := fmt.Sprintf("INSERT INTO "+gc.TableName()+"(ownerid,dstid,cate,memo,createtime,isowner) VALUES %s",
		valueStr)

	if err != nil {
		return 0, err
	}
	ret, err := dbconn.Exec(sqlStr, valueArgs...)
	if err != nil {
		return 0, err
	}
	theID, err := ret.LastInsertId() // 新插入数据的id
	if err != nil {
		return 0, err
	}
	return theID, nil

}